package io.renren.controller;

import io.renren.annotation.Login;
import io.renren.annotation.LoginUser;
import io.renren.common.exception.RRException;
import io.renren.common.utils.AESUtils;
import io.renren.common.utils.ConfigConstant;
import io.renren.common.utils.ProjectConstant;
import io.renren.common.utils.R;
import io.renren.common.validator.Assert;
import io.renren.entity.CenterEntity;
import io.renren.entity.MemberEntity;
import io.renren.entity.RoomEntity;
import io.renren.entity.TeamEntity;
import io.renren.form.RoomConfigForm;
import io.renren.service.CenterService;
import io.renren.service.MemberService;
import io.renren.service.RoomService;
import io.renren.service.SysConfigService;
import io.renren.service.TeamService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;

import java.util.Date;
import java.util.List;

import org.apache.commons.lang.RandomStringUtils;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import springfox.documentation.annotations.ApiIgnore;

import com.baomidou.mybatisplus.enums.SqlLike;
import com.baomidou.mybatisplus.mapper.EntityWrapper;

/**
 * 游戏大厅
 *
 * @author chenshun
 * @email sunlightcs@gmail.com
 * @date 2018-09-03 14:51:31
 */
@RestController
@RequestMapping("/api/game")
@Api(tags = "游戏接口")
public class ApiGameController extends AbstractController {
	@Autowired
	private RoomService roomService;

	@Autowired
	private CenterService centerService;

	@Autowired
	private MemberService memberService;

	@Autowired
	private SysConfigService sysConfigService;

	@Autowired
	private TeamService teamService;

	@Login
	@PostMapping("centers")
	@ApiOperation("游戏大厅")
	public R centers() {
		return R.ok().put("centers", centerService.selectList(new EntityWrapper<CenterEntity>().eq("status", ProjectConstant.COMMON_YES)));
	}

	@Login
	@PostMapping("rooms")
	@ApiOperation("游戏房间")
	public R rooms(@RequestParam Long centerId) {
		return R.ok().put("rooms", roomService.selectList(new EntityWrapper<RoomEntity>().eq("status", ProjectConstant.COMMON_YES).eq("center_id", centerId).eq("is_vip", ProjectConstant.COMMON_NO)));
	}

	@Login
	@PostMapping("gotoRoom")
	@ApiOperation("进入房间")
	public R gotoRoom(@RequestParam Long roomId) {
		MemberEntity member = memberService.selectOne(new EntityWrapper<MemberEntity>().setSqlSelect("id,mobile,room_id,version").eq("id", getUserId()));
		Assert.hasText(member.getMobile(), "您未绑定手机号码");
		RoomEntity room = roomService.selectById(roomId);
		Assert.notNull(room, "房间不存在");
		Assert.isTrue(room.getStatus() == ProjectConstant.COMMON_YES, "房间不存在");
		Assert.isTrue(room.getIsVip() == ProjectConstant.COMMON_NO, "房间不存在");
		Assert.isTrue((room.getPersonOnline() + 1) <= room.getPersonLimit(), "房间已满");

		member.setRoomId(room.getId());
		memberService.updateById(member);

		room.setPersonOnline(room.getPersonOnline() + 1);// 在线人数加1
		roomService.updateById(room);

		return R.ok().put("connectToken", AESUtils.encrypt(DateTime.now().toString("yyyy-MM-dd") + "@" + member.getId() + "@" + member.getMobile()));
	}

	@Login
	@PostMapping("gotoRoomVip")
	@ApiOperation("进入VIP房间")
	public R gotoRoomVip(@RequestParam String roomPwd) {
		MemberEntity member = memberService.selectOne(new EntityWrapper<MemberEntity>().setSqlSelect("id,mobile,room_id,version").eq("id", getUserId()));
		Assert.hasText(member.getMobile(), "您未绑定手机号码");
		Assert.hasText(roomPwd, "房间不存在");
		Assert.isTrue(roomPwd.length() == 6, "房间不存在");
		RoomEntity room = roomService.selectOne(new EntityWrapper<RoomEntity>().eq("vip_room_pwd", roomPwd));
		Assert.notNull(room, "房间不存在");
		Assert.isTrue(room.getStatus() == ProjectConstant.COMMON_YES, "房间不存在");
		Assert.isTrue(room.getIsVip() == ProjectConstant.COMMON_YES, "房间不存在");
		// 房间过期
		if (System.currentTimeMillis() > room.getVipExpireTime().getTime()) {
			room.setStatus(ProjectConstant.COMMON_NO);
			room.setVipRoomPwd("过期");
			roomService.updateById(room);
			throw new RRException("房间不存在");
		}
		Assert.isTrue((room.getPersonOnline() + 1) <= room.getPersonLimit(), "房间已满");

		member.setRoomId(room.getId());
		memberService.updateById(member);

		room.setPersonOnline(room.getPersonOnline() + 1);// 在线人数加1
		roomService.updateById(room);

		return R.ok().put("room", room);
	}

	@Login
	@PostMapping("exitRoom")
	@ApiOperation("退出房间")
	public R exitRoom(@RequestParam Long roomId) {
		RoomEntity room = roomService.selectById(roomId);
		Assert.notNull(room, "房间不存在");
		room.setPersonOnline(room.getPersonOnline() - 1);// 在线人数减1
		roomService.updateById(room);

		MemberEntity member = new MemberEntity();
		member.setId(getUserId());
		member.setRoomId(0L);
		memberService.updateById(member);
		return R.ok();
	}

	@Login
	@PostMapping("myRooms")
	@ApiOperation("我的房间")
	public R myRooms() {
		List<RoomEntity> rooms = roomService.selectList(new EntityWrapper<RoomEntity>().eq("status", ProjectConstant.COMMON_YES).eq("vip_member_id", getUserId()).eq("is_vip", ProjectConstant.COMMON_YES));
		return R.ok().put("rooms", rooms);
	}

	@Login
	@PostMapping("gotoMyRoom")
	@ApiOperation("进入我的房间")
	public R gotoMyRoom(@RequestParam Long roomId) {
		RoomEntity room = roomService.selectById(roomId);
		Assert.notNull(room, "房间不存在");
		Assert.isTrue(room.getStatus() == ProjectConstant.COMMON_YES, "房间不存在");
		Assert.isTrue(room.getIsVip() == ProjectConstant.COMMON_YES, "房间不存在");
		Assert.isTrue(getUserId().equals(room.getVipMemberId()), "房间不存在");
		// 房间过期
		if (System.currentTimeMillis() > room.getVipExpireTime().getTime()) {
			room.setStatus(ProjectConstant.COMMON_NO);
			room.setVipRoomPwd("过期");
			roomService.updateById(room);
			throw new RRException("房间已过期");
		}
		Assert.isTrue((room.getPersonOnline() + 1) <= room.getPersonLimit(), "房间已满");

		MemberEntity member = memberService.selectOne(new EntityWrapper<MemberEntity>().setSqlSelect("id,mobile,room_id,version").eq("id", getUserId()));
		member.setRoomId(room.getId());
		memberService.updateById(member);

		room.setPersonOnline(room.getPersonOnline() + 1);// 在线人数加1
		roomService.updateById(room);

		return R.ok().put("room", room).put("center", centerService.selectById(room.getCenterId()));
	}

	@Login
	@PostMapping("createRoom")
	@ApiOperation("创建房间")
	public R createRoom(@ApiIgnore @LoginUser MemberEntity member) {
		Assert.hasText(member.getMobile(), "您未绑定手机号码");
		CenterEntity center = centerService.selectOne(new EntityWrapper<CenterEntity>().like("center_name", "VIP", SqlLike.RIGHT).last("LIMIT 1"));
		Assert.notNull(center, "VIP大厅不存在");

		RoomConfigForm config = allowCreateRoom(member);

		Date now = new Date();

		RoomEntity room = new RoomEntity();
		room.setCenterId(center.getId());
		room.setPersonLimit(500);
		room.setPersonOnline(1);// 在线人数
		room.setIsVip(ProjectConstant.COMMON_YES);
		room.setMinAmount(config.getMinAmount());
		room.setMaxAmount(config.getMaxAmount());
		room.setPacketQty(sysConfigService.getValue(ConfigConstant.LANDMINE_RETURN_RATES));
		room.setVipRoomPwd(genPwd());
		room.setVipMemberId(member.getId());
		room.setVipExpireTime(new DateTime(now).withTimeAtStartOfDay().plusMonths(12).toDate());
		room.setRoomName("房间" + room.getVipRoomPwd());
		room.setCreateTime(now);
		room.setStatus(ProjectConstant.COMMON_STATUS_ENABLE);
		room.setEnableRobot(ProjectConstant.COMMON_NO);
		roomService.insert(room);

		member.setRoomId(room.getId());
		memberService.updateById(member);

		return R.ok().put("room", room);
	}

	/**
	 * 生成6位随机密码
	 * 
	 * @return
	 */
	private String genPwd() {
		String pwd = RandomStringUtils.randomNumeric(6);
		int i = 0;
		do {
			if (roomService.selectCount(new EntityWrapper<RoomEntity>().eq("vip_room_pwd", pwd)) == 0) {
				return pwd;
			}
			pwd = RandomStringUtils.randomNumeric(6);
			// 最多循环5次
		} while (++i < 5);
		throw new RRException("房间创建失败");
	}

	/**
	 * 创建房间前检查
	 * 
	 * @param member
	 * @return
	 */
	private RoomConfigForm allowCreateRoom(MemberEntity member) {

		int maxRoomCount = sysConfigService.getValueI(ConfigConstant.MAX_ROOM_COUNT);
		int count = roomService.selectCount(new EntityWrapper<RoomEntity>().eq("status", ProjectConstant.COMMON_STATUS_ENABLE).eq("vip_member_id", member.getId()));
		Assert.isTrue(count <= maxRoomCount, "最多允许创建" + maxRoomCount + "个有效房间");

		String[] array = sysConfigService.getValue(ConfigConstant.CREATE_ROOM_LEVEL).split(",");
		// 直推会员
		count = teamService.selectCount(new EntityWrapper<TeamEntity>().eq("higher_one", member.getId()));
		Assert.isTrue(count >= Integer.valueOf(array[0]), "您无法创建房间");

		double sendAmount = teamService.teamSendPacket(member.getId(), DateTime.now().minusMonths(1).toString("yyyy-MM-dd"), null);
		Assert.isTrue(Math.abs(sendAmount) >= Integer.valueOf(array[1]), "您无法创建房间");

		RoomConfigForm config = new RoomConfigForm();
		config.setMinAmount(Integer.valueOf(array[2]));
		config.setMaxAmount(Integer.valueOf(array[3]));
		return config;
	}
}
